package cn.kmsoft.jssc.service.processor;

import cn.kmsoft.jssc.config.AnalyseConfig;
import cn.kmsoft.jssc.entity.analyse.*;
import cn.kmsoft.jssc.service.AnalyseTaskProcessor;
import cn.kmsoft.wololo.object.GeoJson;
import cn.kmsoft.wololo.object.query.GeoJsonQuery;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.util.*;

/**
 * 常规监测图斑-叠加占压分析
 */
public class CgjcAnalyseTaskProcessor extends AnalyseTaskProcessor {
    private static final Logger logger = LoggerFactory.getLogger(CgjcAnalyseTaskProcessor.class);

    //常规监测-地类图斑
    private final String analysePoint="cgjc";
    private AnalyseTaskParam analyseTaskParam;
    private AnalyseConfig analyseConfig;

    public CgjcAnalyseTaskProcessor(AnalyseTaskParam params, AnalyseConfig analyseConfig) {
        this.analyseTaskParam = params;
        this.analyseConfig = analyseConfig;
    }

    public AnalyseTaskParam getAnalyseTaskParam() {
        return analyseTaskParam;
    }
    public void setAnalyseTaskParam(AnalyseTaskParam analyseTaskParam) {
        this.analyseTaskParam = analyseTaskParam;
    }

    @Override
    public TaskResult call() throws Exception {
        // TODO Auto-generated method stub
        String threadId = Thread.currentThread().getName();

        String tableName = this.analyseTaskParam.getTableName();
        String analyseType = this.analyseTaskParam.getAnalystType();

        String dbKey = this.analyseTaskParam.getDbKey();
        AnalyseDb analyseDb = this.analyseConfig.getAnalyseDbByDbkey(dbKey);
        if(analyseDb==null){
            System.out.println();
            String errorMsg = String.format("--->TaskProcessor stop, dbKey: %s, 为null",dbKey);
            System.out.println(errorMsg);
            logger.warn(errorMsg);

            return null;
        }
        String dbType = analyseDb.getDbType();
        String dbInstance = analyseDb.getDbInstance();
        String tablespace = analyseDb.getTablespace();
        String serverId = analyseDb.getServerId();//分析服务标识

        String feaTypePoint = analyseTaskParam.getFeaTypePoint();
        String tableId = dbInstance + "/" + tablespace + "." + tableName;

        //注意，根据数据库类型进行分类处置。
        //若为oracle的sde，则需要添加表空间；
        if("postgresql".equalsIgnoreCase(dbType)){
            //若为postgresql的postgis库，则去掉表空间或者为postgis_33_sample.sde.dltb_2018_500155_d36
            tableId = dbInstance + "/" + dbInstance+"."+ tablespace + "." + tableName;
        }
        String operatorMethod = "intersectpy";
        if(analyseType.equalsIgnoreCase("intersect") && feaTypePoint.equalsIgnoreCase("py")){
            operatorMethod = "intersectpy";
        }else if(analyseType.equalsIgnoreCase("intersect") && feaTypePoint.equalsIgnoreCase("py2")){
            operatorMethod = "intersectpy2";
        }else if(analyseType.equalsIgnoreCase("spatialquery") && feaTypePoint.equalsIgnoreCase("py")){
            operatorMethod = "spatialQuery";
        } else if(analyseType.equalsIgnoreCase("spatialquery") && feaTypePoint.equalsIgnoreCase("py2")){
            operatorMethod = "spatialQuery2";
        } else if(analyseType.equalsIgnoreCase("difference") && feaTypePoint.equalsIgnoreCase("py")){
            operatorMethod = "difference";
        }
        AnalyseServer analyseServer = this.analyseConfig.getAnalyseServerByServerId(serverId);
        String serverUrl = analyseServer.getServerUrl();
        String targetUrl = serverUrl + "/" + operatorMethod + "/" + tableId;

        //String targetUrl = this.analyseConfig.getServerUrl() + "/" + operatorMethod + "/" + tableId;
        //String targetUrl = this.analyseConfig.getServerUrl() + "/" + analysetType + "/" + tableId;
        //String tableId = this.analyseConfig.getDbInstance() + "/" + this.analyseConfig.getDbTablespace() + "." + tableName;
        //String targetUrl = this.analyseConfig.getAnalystServer() + "/" + analystType + "/" + tableId;

        //任务参数
        AnalyseTaskParam params = this.analyseTaskParam;
        params.setTargetUrl(targetUrl);

        TaskResult taskResult = this.startAnalyse(operatorMethod,threadId, params);

        return taskResult;
    }

    /**
     * 开始分析
     * TaskParam params
     * Return
     */
    @Override
    public TaskResult startAnalyse(String operatorMethod,String threadId, AnalyseTaskParam params) {
        TaskResult result = new TaskResult();

        String targetUrl = params.getTargetUrl();
        String jobId=params.getJobId();
        String taskId = params.getTaskId();
        String dkbh = params.getDkbh();
        double dkmj = params.getDkmj();
        int dlhyNf = params.getDlhynf();

        GeoJsonQuery query = (GeoJsonQuery) params.getQuery();
        String tableName= params.getTableName();

        result.setThreadId(threadId);
        result.setJobId(jobId);
        //分析点
        //result.setAnalystPoint(this.analysePoint);
        result.setAnalystPoint(params.getAnalysePoint());
        result.setProcessorName(params.getProcessName());
        result.setTaskId(taskId);
        result.setDkbh(dkbh);
        result.setTableName(tableName);

        System.out.println(String.format("--->doAnalyse,threadId: %s, jobId: %s, dkbh: %s, targetUrl: %s",threadId, jobId, dkbh, targetUrl));
        //核心代码，dltb分析详细结果
        List<DetailResult> detailResultList = this.doCgjcAnalyse(jobId, targetUrl, query);

        result.setDetailsListResult(detailResultList);
        result.setSummary03Result(null);
        //result.setSummary03DBEntResult(ghtzBgdcResults);
        result.setSummary02Result(null);
        result.setSummary01Result(null);

        return result;
    }

    /**
     * dltb叠加分析
     *
     * @param query
     * @return
     */
    public List<DetailResult> doCgjcAnalyse(String jobId, String targetUrl, GeoJsonQuery query) {
        //压盖的详细地类图斑
        List<DetailResult> detailResultList = new ArrayList<DetailResult>();

        String queryJsonStr = JSONObject.toJSONString(query);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<String> entity = new HttpEntity<String>(queryJsonStr, headers);

        //转发分析的请求
        ResponseEntity<JSONObject> exchange = this.exchangeSpatialAnalyst(jobId, targetUrl, entity);
        JSONObject dltbObject= exchange.getBody();
        if(dltbObject==null || dltbObject.getJSONArray("result")==null) {
            return detailResultList;
        }

        String ss = dltbObject.getJSONArray("result").getJSONObject(0).toJSONString();
        //System.out.println( "--->dltbObject: "+ ss);
        GeoJson geojson= JSONObject.parseObject(ss, GeoJson.class);
        JSONArray features = dltbObject.getJSONArray("result").getJSONObject(0).getJSONArray("features");

        //解析后台spatialBoot的叠加分析结果
        //List<Map<String,String>> allFeaProperties = this.parseFeaProperties(features);
        List<Map<String,String>> allFeaProperties = this.parseFeaGeometryAndProperties(features);

        int feaCount = allFeaProperties.size();
        for(int i=0; i<feaCount;i++ ) {
            System.out.println();
            System.out.println(String.format("---->开始第 %d 个要素 ",i+1));

            Map<String,String> feaProps = allFeaProperties.get(i);

            //将要素属性的key全部转为小写，否则oracle和postgresql数据库返回的结果会有差异
            Map<String,String> feaPropsKeyLowercCase = new HashMap<>();
            feaProps.forEach((key,value) -> feaPropsKeyLowercCase.put(key.toLowerCase(), value));


            /*
            //常规监测图层
            //打印所有字段结构
            Set<String> propKeySet = feaProps.keySet();
            Iterator<String> iter = propKeySet.iterator();
            while (iter.hasNext()){
                String propKey = iter.next();
                String propVal = feaProps.get(propKey);

                System.out.println(String.format("propKey： %s, propVal： %s",propKey,propVal));
            }
            */
            //1-目标图层的字段值
            String tbbh = feaPropsKeyLowercCase.get("tbbh").toString();

            //2-追加的3个几何面积
            double area = Double.parseDouble(feaPropsKeyLowercCase.get("area").toString());//叠加后重叠范围的几何面积
            double fgeoarea = Double.parseDouble(feaPropsKeyLowercCase.get("fgeoarea").toString());//目标图层（sde库）原图斑几何面积
            double sgeoarea = Double.parseDouble(feaPropsKeyLowercCase.get("sgeoarea").toString());//上传图斑的几何面积

            //3-叠加相交结果的几何图形
            String geomText = feaPropsKeyLowercCase.get("geom").toString();

            DetailResult dltbDetail = new DetailResult();
            dltbDetail.setTbbh(tbbh);
            //后台新建的新面积字段
            dltbDetail.setArea(Math.abs(area));//叠加相交面积，核心成果
            dltbDetail.setFgeoarea(Math.abs(fgeoarea));//sde原图斑几何面积
            dltbDetail.setSgeoarea(Math.abs(sgeoarea));//上传图斑几何面积
            //图形
            dltbDetail.setGeomText(geomText);
            //其他详细字段信息
            dltbDetail.setFeaProps(feaProps);

            detailResultList.add(dltbDetail);
        }

        return detailResultList;
    }
}
